package com.btech.dftp.dataimport.dao;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.quincy.rock.core.util.CoreUtil;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * <b>BatchDetailDao。</b>
 * <p><b>详细说明：</b></p>
 * <!-- 在此添加详细说明 -->
 * 无。
 * <p><b>修改列表：</b></p>
 * <table width="100%" cellSpacing=1 cellPadding=3 border=1>
 * <tr bgcolor="#CCCCFF"><td>序号</td><td>作者</td><td>修改日期</td><td>修改内容</td></tr>
 * <!-- 在此添加修改列表，参考第一行内容 -->
 * <tr><td>1</td><td>wks</td><td>2022年4月21日 下午5:42:51</td><td>建立类型</td></tr>
 * 
 * </table>
 * @version 1.0
 * @author wks
 * @since 1.0
 */
@Transactional(readOnly = true)
@SuppressWarnings({ "unchecked", "rawtypes" })
public abstract class BatchDetailDao extends BaseDao {
	/**
	 * 主表名。
	 */
	private String mainTable;
	/**
	 * 明细表名。
	 */
	private String detailTable;
	/**
	 * mainSqlName。
	 */
	private String mainSqlName;
	/**
	 * detailSqlName。
	 */
	private String detailSqlName;
	
	private int batchSize=20;
	
	/**
	 * batch缓存列表
	 */
	private final List<Map<String, Object>> cacheList = new ArrayList<Map<String, Object>>();

	/**
	 * <b>构造方法。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param mainTable 主表名
	 * @param detailTable 明细表名
	 * @param sqlKey sql语句的key
	 */
	public BatchDetailDao(String mainTable, String detailTable, String sqlKey) {
		this.mainTable = mainTable;
		this.detailTable = detailTable;
		this.mainSqlName = sqlKey;
		this.detailSqlName = sqlKey + "Detail";
	}

	/**
	 * <b>getBatchSize。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @return
	 */
	public int getBatchSize() {
		return batchSize;
	}

	/**
	 * <b>setBatchSize。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param batchSize
	 */
	public void setBatchSize(int batchSize) {
		this.batchSize = batchSize;
	}

	/**
	 * <b>插入一条报关单数据。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 货物key是detail。
	 * @param data 报关单数据,包含货物明细
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void insertData(Map<String, Object> data) {
		cacheList.add(data);
		if (cacheList.size() >= batchSize) {
			this.flush();
		}
	}

	/**
	 * <b>刷新缓存到数据库。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void flush() {
		if (cacheList.isEmpty())
			return;
		List<Map<String, Object>> mainList = cacheList;

		List<Map<String, Object>> detailList = new ArrayList<Map<String, Object>>();
		for (Map<String, Object> mainData : mainList) {
			Long mainId = idGenerator.generate(mainTable);
			mainData.put("id", mainId);
			List<Map<String, Object>> detail = (List) mainData.get("detail");
			if (!CoreUtil.isEmpty(detail)) {
				for (Map<String, Object> detailData : detail) {
					Long id = idGenerator.generate(detailTable);
					detailData.put("id", id);
					detailData.put("mainId", mainId);
					detailList.add(detailData);
				}
			}
		}
		//保存主表数据
		String mainSql = daoSupport.getNamedSql(mainSqlName, mainTable);
		daoSupport.batchByNaming(mainSql, mainList);

		String detailSql = daoSupport.getNamedSql(detailSqlName, detailTable);
		daoSupport.batchByNaming(detailSql, detailList);

		LOGGER.info("BatchDetailDao:This batch inserts {} data to table {}.", mainList.size(), mainTable);
		//清空
		cacheList.clear();
	}
}
